package com.jlboot.core.util;

import com.jfinal.kit.StrKit;
import com.jlboot.core.exception.JlLogicException;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wangsanfei
 * @version 1.0
 * Create by 2024/1/8 14:26
 */
public class SearchUtil {

    /**
     * 等于
     */
    public static final String eq="eq";

    /**
     * 模糊查询
     */
    public static final String like="like";

    /**
     * 模糊左查询
     */
    public static final String like_left="like_left";

    /**
     * 模糊又查询
     */
    public static final String like_right="like_right";
    /**
     * 大于
     */
    public static final String gt="gt";
    /**
     * 小于
     */
    public static final String lt="lt";
    /**
     * 大于等于
     */
    public static final String ge="ge";
    /**
     * 小于等于
     */
    public static final String le="le";
    /**
     * in
     */
    public static final String in="in";


    private static final String empty="";
    private static final String start="[";
    private static final String end="]";
    private static final String concat_op_and=" and ";
    private static final String concat_op_or=" or ";

    private static final List<String> ops;

    static{
        ops=new ArrayList<>();
        ops.add(eq);
        ops.add(like);
        ops.add(like_left);
        ops.add(like_right);
        ops.add(gt);
        ops.add(lt);
        ops.add(ge);
        ops.add(le);
        ops.add(in);
    }

    /**
     * 判断是不是标准的查询Key
     * @param searchKey
     * @return
     */
    public static boolean is_search_key(String searchKey){
        for (String op : ops) {
            if(operate_is(op,searchKey)){
                return true;
            }
        }
        return false;
    }

    public static SearchSqlObject create_and_sql(String searchKey,Object searchValue){
        return create_sql(concat_op_and,searchKey,searchValue);
    }

    public static SearchSqlObject create_or_sql(String searchKey,Object searchValue){
        return create_sql(concat_op_or,searchKey,searchValue);
    }


    /////////////////////////////////

    /**
     * 根据查询Key创建SQL
     * @param concat_op
     * @param searchKey
     * @param searchValue
     * @return
     */
    private static SearchSqlObject create_sql(String concat_op, String searchKey,Object searchValue){

        if(searchValue==null){
            throw new JlLogicException("searchValue不能为空");
        }
        if(searchValue instanceof String){
            if(StrKit.isBlank(searchValue.toString())){
                throw new JlLogicException("searchValue为String类型时候不能为空字符串");
            }
        }

        SearchSqlObject searchSqlObject=new SearchSqlObject();

        StringBuilder sql=new StringBuilder();
        for (String op : ops) {
            if(operate_is(op,searchKey)){
                String key=operate_parse(op,searchKey);
                if(eq.equals(op)){
                    sql.append(concat_op).append(key).append(" = ? ");
                    searchSqlObject.getValues().add(searchValue);
                }else if(like.equals(op)){
                    sql.append(concat_op).append(key).append(" like ? ");
                    searchSqlObject.getValues().add("%"+searchValue+"%");
                }else if(like_left.equals(op)){
                    sql.append(concat_op).append(key).append(" like ? ");
                    searchSqlObject.getValues().add("%"+searchValue);
                }else if(like_right.equals(op)){
                    sql.append(concat_op).append(key).append(" like ? ");
                    searchSqlObject.getValues().add(searchValue+"%");
                }else if(gt.equals(op)){
                    sql.append(concat_op).append(key).append(" > ? ");
                    searchSqlObject.getValues().add(searchValue);
                }else if(lt.equals(op)){
                    sql.append(concat_op).append(key).append(" < ? ");
                    searchSqlObject.getValues().add(searchValue);
                }else if(ge.equals(op)){
                    sql.append(concat_op).append(key).append(" >= ? ");
                    searchSqlObject.getValues().add(searchValue);
                }else if(le.equals(op)){
                    sql.append(concat_op).append(key).append(" <= ? ");
                    searchSqlObject.getValues().add(searchValue);
                }else if(in.equals(op)){
                    Object[] ss=null;
                    if(searchValue instanceof List){
                        ss=((List)searchValue).toArray();
                    }else if(searchValue instanceof Object[]){
                        ss=(Object[])searchValue;
                    }else if(searchValue instanceof String){
                        ss=((String)searchValue).split(",");
                    }

                    if(ss==null||ss.length==0){
                        throw new RuntimeException("searchValue不能为空");
                    }

                    sql.append(concat_op).append(key).append(" in ( ");
                    for (int i = 0; i < ss.length; i++) {
                        if(i>0){
                            sql.append(",");
                        }
                        sql.append("?");
                        searchSqlObject.getValues().add(ss[i]);
                    }
                    sql.append(") ");
                }else{
                    throw new RuntimeException("searchKey不是标准的查询操作符号");
                }

            }
        }
        searchSqlObject.setSql(sql.toString());
        return searchSqlObject;
    }

    /**
     * 创建查询Key
     * @param operator
     * @param column
     * @return
     */
    public static String operate(String operator,String column){
        return operator+start+column+end;
    }

    /**
     * 解析查询Key
     * @param operator
     * @param key
     * @return
     */
    private static String operate_parse(String operator,String key){
        String newKey=key.replaceFirst(operator+"\\"+start,empty);
        newKey=newKey.substring(0,newKey.length()-end.length());
        return newKey;
    }

    /**
     * 是否是标准查询Key
     * @param operator
     * @param searchKey
     * @return
     */
    private static boolean operate_is(String operator,String searchKey){
        if(searchKey.startsWith(operator+start)&&searchKey.endsWith(end)){
            return true;
        }
        return false;
    }

    /**
     * 获取标准查询
     * @param searchKey
     * @return
     */
    private static String operate_symbol(String searchKey){
        for (String op : ops) {
            if(searchKey.startsWith(op+start)){
                return op;
            }
        }
        throw new JlLogicException("searchKey不是标准的查询操作符号");
    }

    @Data
    public static class SearchSqlObject{
        private String sql;
        private List<Object> values=new ArrayList<>();
    }

}
